﻿using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.Persistent.Base;
using EasyXaf.EntityDesigner.BusinessObjects;

namespace EasyXaf.EntityDesigner.Controllers;

public class CloneDomainModelViewController : ObjectViewController<ObjectView, DomainModel>
{
    public SimpleAction CloneModelAction { get; }

    public CloneDomainModelViewController()
    {
        TargetViewNesting = Nesting.Root;

        CloneModelAction = new SimpleAction(this, "CloneModelAction", PredefinedCategory.ObjectsCreation)
        {
            Caption = "克隆",
            ImageName = "Action_CloneMerge_Clone_Object",
            SelectionDependencyType = SelectionDependencyType.RequireSingleObject,
        };
    }

    protected override void OnActivated()
    {
        base.OnActivated();

        CloneModelAction.Execute += CloneModelAction_Execute;
    }

    protected override void OnDeactivated()
    {
        CloneModelAction.Execute -= CloneModelAction_Execute;

        base.OnDeactivated();
    }

    private void CloneModelAction_Execute(object sender, SimpleActionExecuteEventArgs e)
    {
        if (e.CurrentObject is DomainModel domainModel)
        {
            var objectSpace = Application.CreateObjectSpace(typeof(DomainModel));

            domainModel = objectSpace.GetObject(domainModel);
            domainModel = new Cloner().CloneTo(domainModel, typeof(DomainModel)) as DomainModel;

            var parentDomainModels = objectSpace.GetObjectsQuery<DomainModel>().ToList()
                .Where(m => m.ReferenceModels.Contains(domainModel))
                .ToList();

            foreach (var parentDomainModel in parentDomainModels)
            {
                parentDomainModel.ReferenceModels.Remove(domainModel);
            }

            var view = Application.CreateDetailView(objectSpace, domainModel);

            void ObjectSpace_Committed(object sender, EventArgs e)
            {
                ObjectSpace.Refresh();
            }

            Application.ShowViewStrategy.ShowViewInPopupWindow(view, () =>
            {
                objectSpace.Committed -= ObjectSpace_Committed;
                objectSpace.Committed += ObjectSpace_Committed;
            });
        }
    }
}
